<template>
    <div class="matchground">
        <!-- 背景动画效果 -->
        <div class="background-animation">
            <div class="particle"></div>
            <div class="particle"></div>
            <div class="particle"></div>
            <div class="particle"></div>
            <div class="particle"></div>
        </div>

        <!-- 用户信息行 -->
        <div class="players-container">
            <!-- 当前用户 -->
            <div class="player-card current-player">
                <div class="player-status">
                    <div class="status-indicator online"></div>
                    <span class="status-text">在线</span>
                </div>
                <div class="player-avatar">
                    <div v-if="!userStore.photo" class="avatar-loading">
                        <div class="loading-spinner"></div>
                    </div>
                    <img
                        v-else
                        :src="userStore.photo"
                        alt="玩家头像"
                        class="avatar-image"
                        @load="handleImageLoad"
                        :class="{ loaded: imageLoaded }"
                    />
                    <div class="avatar-glow"></div>
                </div>
                <div class="player-info">
                    <h3 class="player-name">{{ userStore.username }}</h3>
                    <div class="player-stats">
                        <div class="stat">
                            <i class="fas fa-trophy"></i>
                            <span>胜率: 65%</span>
                        </div>
                        <div class="stat">
                            <i class="fas fa-star"></i>
                            <span>等级: 12</span>
                        </div>
                    </div>
                </div>
            </div>

            <!-- VS 标志 -->
            <div class="vs-container">
                <div class="vs-text">VS</div>
                <div class="vs-line"></div>
            </div>

            <!-- 对手1 -->
            <div class="player-card opponent">
                <div class="player-status">
                    <div
                        class="status-indicator"
                        :class="{ online: gameStore.opponents.player1.photo }"
                    ></div>
                    <span class="status-text">{{
                        gameStore.opponents.player1.photo ? '等待中' : '未匹配'
                    }}</span>
                </div>
                <div class="player-avatar">
                    <div v-if="!gameStore.opponents.player1.photo" class="avatar-loading">
                        <div class="loading-spinner"></div>
                    </div>
                    <img
                        v-else
                        :src="gameStore.opponents.player1.photo"
                        alt="对手头像"
                        class="avatar-image"
                        @load="handleImageLoad"
                        :class="{ loaded: imageLoaded }"
                    />
                    <div class="avatar-glow"></div>
                </div>
                <div class="player-info">
                    <h3 class="player-name">{{ gameStore.opponent1_username || '等待匹配...' }}</h3>
                    <div class="player-stats">
                        <div class="stat">
                            <i class="fas fa-trophy"></i>
                            <span>胜率: --</span>
                        </div>
                        <div class="stat">
                            <i class="fas fa-star"></i>
                            <span>等级: --</span>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 对手2 -->
            <div class="player-card opponent">
                <div class="player-status">
                    <div
                        class="status-indicator"
                        :class="{ online: gameStore.opponents.player2.photo }"
                    ></div>
                    <span class="status-text">{{
                        gameStore.opponents.player2.photo ? '等待中' : '未匹配'
                    }}</span>
                </div>
                <div class="player-avatar">
                    <div v-if="!gameStore.opponents.player2.photo" class="avatar-loading">
                        <div class="loading-spinner"></div>
                    </div>
                    <img
                        v-else
                        :src="gameStore.opponents.player2.photo"
                        alt="队友头像"
                        class="avatar-image"
                        @load="handleImageLoad"
                        :class="{ loaded: imageLoaded }"
                    />
                    <div class="avatar-glow"></div>
                </div>
                <div class="player-info">
                    <h3 class="player-name">{{ gameStore.opponent2_username || '等待匹配...' }}</h3>
                    <div class="player-stats">
                        <div class="stat">
                            <i class="fas fa-trophy"></i>
                            <span>胜率: --</span>
                        </div>
                        <div class="stat">
                            <i class="fas fa-star"></i>
                            <span>等级: --</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 匹配控制区域 -->
        <div class="match-controls">
            <div class="match-button-container">
                <button
                    @click="click_match_btn"
                    class="match-button"
                    :class="{ matching: match_btn_info === '取消' }"
                >
                    <span class="button-content">
                        <i
                            class="fas"
                            :class="match_btn_info === '开始匹配' ? 'fa-play' : 'fa-stop'"
                        ></i>
                        {{ match_btn_info }}
                    </span>
                    <div class="button-glow"></div>
                </button>
            </div>
            <div class="invite-button-container">
                <button @click="toggleFriendsList" class="invite-button">
                    <span class="button-content">
                        <i class="fas fa-user-plus"></i>
                        邀请好友
                    </span>
                    <div class="button-glow"></div>
                </button>
            </div>
        </div>

        <!-- 好友列表弹窗 -->
        <div class="modal-overlay" v-if="showFriendsList" @click="toggleFriendsList">
            <div class="modal-content" @click.stop>
                <div class="modal-header">
                    <h3>邀请好友</h3>
                    <button @click="toggleFriendsList" class="close-button">
                        <i class="fas fa-times"></i>
                    </button>
                </div>
                <div class="modal-body">
                    <div v-if="loading" class="loading-container">
                        <div class="loading-spinner"></div>
                        <p>加载中...</p>
                    </div>
                    <div v-else-if="friends.length === 0" class="empty-state">
                        <i class="fas fa-user-friends"></i>
                        <p>您还没有好友，请先添加好友。</p>
                    </div>
                    <div v-else class="friends-grid">
                        <div v-for="friend in friends" :key="friend.id" class="friend-card">
                            <div class="friend-avatar">
                                <img :src="friend.photo" alt="好友头像" />
                            </div>
                            <div class="friend-info">
                                <h4>{{ friend.username }}</h4>
                                <div class="friend-status online">在线</div>
                            </div>
                            <button @click="inviteFriend(friend.id)" class="invite-action">
                                <i class="fas fa-gamepad"></i>
                                邀请
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 游戏邀请弹窗 -->
        <div class="modal-overlay" v-if="showGameInvitation">
            <div class="modal-content game-invitation" @click.stop>
                <div class="modal-header">
                    <h3>游戏邀请</h3>
                    <button @click="closeGameInvitation" class="close-button">
                        <i class="fas fa-times"></i>
                    </button>
                </div>
                <div class="modal-body">
                    <div class="inviter-profile">
                        <div class="inviter-avatar">
                            <img :src="invitationData.photo" alt="邀请人头像" />
                            <div class="avatar-glow"></div>
                        </div>
                        <h4>{{ invitationData.username }}</h4>
                        <p class="invite-message">邀请您一起游戏</p>
                    </div>
                    <div class="invitation-actions">
                        <button @click="acceptGameInvitation" class="accept-button">
                            <i class="fas fa-check"></i>
                            接受
                        </button>
                        <button @click="rejectGameInvitation" class="reject-button">
                            <i class="fas fa-times"></i>
                            拒绝
                        </button>
                    </div>
                    <div class="invitation-timer">
                        <div class="timer-progress" :style="{ width: `${timerProgress}%` }"></div>
                        <span class="timer-text">{{ timerSeconds }}秒后自动拒绝</span>
                    </div>
                </div>
            </div>
        </div>

        <!-- 提示消息 -->
        <div class="toast-container" v-if="showToast">
            <div class="toast" :class="toastType">
                <i
                    class="fas"
                    :class="{
                        'fa-check-circle': toastType === 'success',
                        'fa-exclamation-circle': toastType === 'error',
                        'fa-info-circle': toastType === 'info',
                    }"
                ></i>
                {{ toastMessage }}
            </div>
        </div>
    </div>
</template>

<script>
import { useGameStore } from '@/store/game'
import { useUserStore } from '@/store/user'
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import axios from 'axios'

export default {
    props: {
        gameInvitation: {
            type: Object,
            default: null,
        },
    },
    setup(props) {
        const gameStore = useGameStore()
        const userStore = useUserStore()

        const match_btn_info = ref('开始匹配')
        const showFriendsList = ref(false)
        const friends = ref([])
        const loading = ref(false)
        const showToast = ref(false)
        const toastMessage = ref('')
        const toastType = ref('')
        const pageNum = ref(1)
        const pageSize = ref(50)
        const totalPages = ref(0)
        const totalCount = ref(0)
        const mounted = ref(false)
        const imageLoaded = ref(false)

        // 游戏邀请相关状态
        const showGameInvitation = ref(false)
        const localGameInvitation = ref({})
        const timerSeconds = ref(10)
        const timerProgress = ref(100)
        let invitationTimer = null

        const handleImageLoad = () => {
            imageLoaded.value = true
        }

        // 监听gameInvitation属性的变化
        watch(
            () => props.gameInvitation,
            (newVal) => {
                if (newVal) {
                    console.log('MatchGround收到游戏邀请属性:', newVal)
                    localGameInvitation.value = { ...newVal }
                    showGameInvitation.value = true
                    resetInvitationTimer()
                }
            },
            { immediate: true }
        )

        const click_match_btn = () => {
            if (!gameStore.socket) {
                showToastMessage('error', 'WebSocket连接未建立，请稍后再试')
                return
            }

            if (match_btn_info.value === '开始匹配') {
                match_btn_info.value = '取消'
                gameStore.socket.send(
                    JSON.stringify({
                        event: 'start-matching',
                    })
                )
            } else {
                match_btn_info.value = '开始匹配'
                gameStore.socket.send(
                    JSON.stringify({
                        event: 'stop-matching',
                    })
                )
            }
        }

        const toggleFriendsList = () => {
            showFriendsList.value = !showFriendsList.value
            if (showFriendsList.value) {
                loadFriends()
            }
        }

        const loadFriends = async () => {
            try {
                loading.value = true
                const response = await axios.get('https://www.xujiaojiaojiao.cn/api/friend/list/', {
                    params: {
                        pageNum: pageNum.value,
                        pageSize: pageSize.value,
                        _t: Date.now(),
                    },
                    headers: {
                        Authorization: `Bearer ${userStore.token}`,
                    },
                })
                if (response.data.code === 1) {
                    userStore.friends = JSON.parse(JSON.stringify(response.data.data.records))
                    friends.value = [...userStore.friends]
                    totalPages.value = Number(response.data.data.pages)
                    totalCount.value = Number(response.data.data.total)
                    mounted.value = true
                }
            } catch (error) {
                console.error('加载好友列表失败:', error)
                friends.value = []
            } finally {
                loading.value = false
            }
        }

        const inviteFriend = (friendId) => {
            if (!gameStore.socket) {
                showToastMessage('error', 'WebSocket连接未建立，请稍后再试')
                return
            }

            gameStore.socket.send(
                JSON.stringify({
                    event: 'game-invite',
                    toUserId: friendId,
                })
            )
            showToastMessage('success', '邀请已发送')
            toggleFriendsList()
        }

        const showToastMessage = (type, message) => {
            toastType.value = type
            toastMessage.value = message
            showToast.value = true

            setTimeout(() => {
                showToast.value = false
            }, 3000)
        }

        // 重置邀请计时器
        const resetInvitationTimer = () => {
            // 清除现有计时器
            if (invitationTimer) {
                clearInterval(invitationTimer)
                invitationTimer = null
            }

            // 重置计时器状态
            timerSeconds.value = 10
            timerProgress.value = 100

            // 启动新计时器
            invitationTimer = setInterval(() => {
                timerSeconds.value--
                timerProgress.value = (timerSeconds.value / 10) * 100

                if (timerSeconds.value <= 0) {
                    // 时间到，自动拒绝邀请
                    rejectGameInvitation()
                    showToastMessage('info', '邀请已超时自动拒绝')
                }
            }, 1000)
        }

        // 关闭游戏邀请窗口
        const closeGameInvitation = () => {
            showGameInvitation.value = false

            // 清除计时器
            if (invitationTimer) {
                clearInterval(invitationTimer)
                invitationTimer = null
            }
        }

        // 接受游戏邀请
        const acceptGameInvitation = () => {
            if (!gameStore.socket) {
                showToastMessage('error', 'WebSocket连接未建立，请稍后再试')
                return
            }

            gameStore.socket.send(
                JSON.stringify({
                    event: 'game-invite-result',
                    toUserId: localGameInvitation.value.fromUserId,
                    response: 'accept',
                })
            )

            closeGameInvitation()
            // 不再显示提示消息，由PkindexView处理
        }

        // 拒绝游戏邀请
        const rejectGameInvitation = () => {
            if (!gameStore.socket) {
                showToastMessage('error', 'WebSocket连接未建立，请稍后再试')
                return
            }

            gameStore.socket.send(
                JSON.stringify({
                    event: 'game-invite-result',
                    toUserId: localGameInvitation.value.fromUserId,
                    response: 'reject',
                })
            )

            closeGameInvitation()
            // 不再显示提示消息，由PkindexView处理
        }

        onMounted(() => {
            console.log('MatchGround组件已挂载')
            // 不再初始化WebSocket连接，使用PkindexView中的连接
        })

        onBeforeUnmount(() => {
            if (invitationTimer) {
                clearInterval(invitationTimer)
                invitationTimer = null
            }
        })

        return {
            gameStore,
            userStore,
            match_btn_info,
            click_match_btn,
            showFriendsList,
            toggleFriendsList,
            friends,
            loading,
            inviteFriend,
            showToast,
            toastMessage,
            toastType,
            showToastMessage,
            showGameInvitation,
            invitationData: localGameInvitation,
            acceptGameInvitation,
            rejectGameInvitation,
            closeGameInvitation,
            timerSeconds,
            timerProgress,
            imageLoaded,
            handleImageLoad,
        }
    },
}
</script>

<style scoped>
.matchground {
    width: 100%;
    height: 100%;
    max-width: 1200px;
    min-height: 80vh;
    background: linear-gradient(135deg, rgba(20, 20, 20, 0.95) 0%, rgba(40, 40, 40, 0.95) 100%);
    border-radius: 30px;
    margin: 2rem auto;
    padding: 2rem;
    position: relative;
    overflow: hidden;
    box-shadow: 0 0 50px rgba(0, 0, 0, 0.5);
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.background-animation {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
    z-index: 0;
}

.particle {
    position: absolute;
    width: 4px;
    height: 4px;
    background: rgba(40, 167, 69, 0.5);
    border-radius: 50%;
    animation: float 15s infinite linear;
}

.particle:nth-child(1) {
    left: 10%;
    animation-delay: 0s;
}
.particle:nth-child(2) {
    left: 30%;
    animation-delay: 2s;
}
.particle:nth-child(3) {
    left: 50%;
    animation-delay: 4s;
}
.particle:nth-child(4) {
    left: 70%;
    animation-delay: 6s;
}
.particle:nth-child(5) {
    left: 90%;
    animation-delay: 8s;
}

@keyframes float {
    0% {
        transform: translateY(-100%) rotate(0deg);
        opacity: 0;
    }
    50% {
        opacity: 1;
    }
    100% {
        transform: translateY(1000%) rotate(360deg);
        opacity: 0;
    }
}

.players-container {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 2rem;
    position: relative;
    z-index: 1;
    margin: 2rem 0;
    min-height: 400px;
}

.player-card {
    background: rgba(30, 30, 30, 0.8);
    border-radius: 20px;
    padding: 1.5rem;
    width: 280px;
    text-align: center;
    position: relative;
    transition: all 0.3s ease;
    border: 1px solid rgba(40, 167, 69, 0.3);
    box-shadow: 0 0 20px rgba(40, 167, 69, 0.1);
    margin: 0;
}

.player-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 10px 30px rgba(40, 167, 69, 0.2);
}

.current-player {
    background: linear-gradient(145deg, rgba(40, 167, 69, 0.2), rgba(30, 30, 30, 0.8));
}

.player-status {
    position: absolute;
    top: 1rem;
    right: 1rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.status-indicator {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #666;
}

.status-indicator.online {
    background: #28a745;
    box-shadow: 0 0 10px #28a745;
}

.status-text {
    font-size: 0.8rem;
    color: #aaa;
}

.player-avatar {
    width: 120px;
    height: 120px;
    margin: 0 auto 1rem;
    position: relative;
}

.avatar-loading {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    background: rgba(40, 167, 69, 0.1);
    border-radius: 50%;
}

.loading-spinner {
    width: 40px;
    height: 40px;
    border: 4px solid rgba(40, 167, 69, 0.3);
    border-top: 4px solid #28a745;
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

.avatar-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
    border: 3px solid #28a745;
    transition: all 0.5s ease;
    opacity: 0;
    transform: scale(0.8);
}

.avatar-image.loaded {
    opacity: 1;
    transform: scale(1);
}

.avatar-glow {
    position: absolute;
    top: -5px;
    left: -5px;
    right: -5px;
    bottom: -5px;
    border-radius: 50%;
    background: radial-gradient(circle at center, rgba(40, 167, 69, 0.3), transparent 70%);
    animation: pulse 2s infinite;
}

.player-info {
    margin-top: 1rem;
}

.player-name {
    color: #fff;
    font-size: 1.2rem;
    margin-bottom: 0.5rem;
}

.player-stats {
    display: flex;
    justify-content: center;
    gap: 1rem;
}

.stat {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: #aaa;
    font-size: 0.9rem;
}

.vs-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    margin: 0 1rem;
}

.vs-text {
    font-size: 2rem;
    font-weight: bold;
    color: #28a745;
    text-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
}

.vs-line {
    width: 2px;
    height: 100px;
    background: linear-gradient(to bottom, transparent, #28a745, transparent);
}

.match-controls {
    margin-top: auto;
    display: flex;
    justify-content: center;
    gap: 2rem;
    position: relative;
    z-index: 1;
    padding: 2rem 0;
}

.match-button,
.invite-button {
    padding: 1rem 2.5rem;
    border: none;
    border-radius: 50px;
    font-size: 1.1rem;
    color: white;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: all 0.3s ease;
}

.match-button {
    background: linear-gradient(145deg, #28a745, #1e7e34);
}

.invite-button {
    background: linear-gradient(145deg, #007bff, #0056b3);
}

.match-button.matching {
    animation: pulse 2s infinite;
}

.button-content {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.button-glow {
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.1), transparent);
    transform: rotate(45deg);
    animation: shine 3s infinite;
}

.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.8);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 1000;
    backdrop-filter: blur(5px);
}

.modal-content {
    background: linear-gradient(145deg, rgba(30, 30, 30, 0.95), rgba(20, 20, 20, 0.95));
    border-radius: 20px;
    width: 90%;
    max-width: 500px;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
    position: relative;
    border: 1px solid rgba(40, 167, 69, 0.3);
    box-shadow: 0 0 30px rgba(40, 167, 69, 0.2);
}

.modal-header {
    padding: 1.5rem;
    border-bottom: 1px solid rgba(40, 167, 69, 0.3);
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-shrink: 0;
}

.modal-header h3 {
    color: #28a745;
    margin: 0;
}

.close-button {
    background: none;
    border: none;
    color: #aaa;
    font-size: 1.2rem;
    cursor: pointer;
    transition: color 0.3s ease;
}

.close-button:hover {
    color: #fff;
}

.modal-body {
    padding: 1.5rem;
    overflow-y: auto;
    flex: 1;
    min-height: 0;
    max-height: calc(80vh - 80px);
}

.friends-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: 100px;
    gap: 1rem;
    padding-right: 0.5rem;
    /* 新增滚动设置 */
    max-height: 420px; /* (100px行高 + 1rem间隙)*4 */
    overflow-y: auto;
}

.friend-card {
    background: rgba(40, 40, 40, 0.6);
    border-radius: 15px;
    padding: 1rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    transition: all 0.3s ease;
    border: 1px solid rgba(40, 167, 69, 0.2);
    height: 100%;
    min-height: 100px;
}

.friend-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 5px 15px rgba(40, 167, 69, 0.2);
    border-color: rgba(40, 167, 69, 0.4);
}

.friend-avatar {
    width: 50px;
    height: 50px;
    border-radius: 50%;
    overflow: hidden;
    flex-shrink: 0;
}

.friend-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.friend-info {
    flex: 1;
    min-width: 0;
    overflow: hidden;
}

.friend-info h4 {
    color: #fff;
    margin: 0 0 0.3rem 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.friend-status {
    font-size: 0.8rem;
    color: #28a745;
}

.invite-action {
    background: #28a745;
    border: none;
    color: white;
    padding: 0.5rem 1rem;
    border-radius: 5px;
    cursor: pointer;
    transition: all 0.3s ease;
    white-space: nowrap;
    flex-shrink: 0;
}

.invite-action:hover {
    background: #218838;
    transform: scale(1.05);
}

.game-invitation {
    text-align: center;
}

.inviter-profile {
    margin-bottom: 2rem;
}

.inviter-avatar {
    width: 100px;
    height: 100px;
    margin: 0 auto 1rem;
    position: relative;
}

.inviter-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
    border: 3px solid #28a745;
}

.invite-message {
    color: #aaa;
    margin: 0.5rem 0;
}

.invitation-actions {
    display: flex;
    justify-content: center;
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.accept-button,
.reject-button {
    padding: 0.8rem 2rem;
    border: none;
    border-radius: 5px;
    font-size: 1rem;
    cursor: pointer;
    transition: all 0.3s ease;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.accept-button {
    background: #28a745;
    color: white;
}

.reject-button {
    background: #dc3545;
    color: white;
}

.invitation-timer {
    position: relative;
    height: 20px;
    background: rgba(0, 0, 0, 0.3);
    border-radius: 10px;
    overflow: hidden;
}

.timer-progress {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    background: linear-gradient(90deg, #28a745, #1e7e34);
    transition: width 1s linear;
}

.timer-text {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 0.8rem;
}

.toast-container {
    position: fixed;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1100;
}

.toast {
    padding: 1rem 2rem;
    border-radius: 8px;
    color: white;
    font-size: 1rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    animation: slideUp 0.3s ease, fadeOut 0.3s ease 2.7s;
}

.toast.success {
    background: rgba(40, 167, 69, 0.9);
}

.toast.error {
    background: rgba(220, 53, 69, 0.9);
}

.toast.info {
    background: rgba(13, 110, 253, 0.9);
}

@keyframes spin {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

@keyframes pulse {
    0% {
        box-shadow: 0 0 0 0 rgba(40, 167, 69, 0.4);
    }
    70% {
        box-shadow: 0 0 0 10px rgba(40, 167, 69, 0);
    }
    100% {
        box-shadow: 0 0 0 0 rgba(40, 167, 69, 0);
    }
}

@keyframes shine {
    0% {
        transform: translateX(-100%) rotate(45deg);
    }
    100% {
        transform: translateX(100%) rotate(45deg);
    }
}

@keyframes slideUp {
    from {
        transform: translate(-50%, 100%);
        opacity: 0;
    }
    to {
        transform: translate(-50%, 0);
        opacity: 1;
    }
}

@keyframes fadeOut {
    from {
        opacity: 1;
    }
    to {
        opacity: 0;
    }
}

@media (max-width: 768px) {
    .matchground {
        width: 100%;
        margin: 0;
        border-radius: 0;
        min-height: 100vh;
        padding: 1rem;
    }

    .players-container {
        flex-direction: column;
        gap: 1rem;
        min-height: auto;
        margin: 1rem 0;
    }

    .player-card {
        width: 100%;
        max-width: 300px;
    }

    .vs-container {
        display: none;
    }

    .match-controls {
        flex-direction: column;
        align-items: center;
        padding: 1rem 0;
    }

    .match-button,
    .invite-button {
        width: 100%;
        max-width: 300px;
    }

    .friends-grid {
        grid-template-columns: 1fr; /* 单列显示 */
        grid-auto-rows: 80px; /* 减小行高 */
        max-height: 360px; /* (80px行高 + 1rem间隙)*4 */
    }

    .friend-card {
        height: 80px;
        min-height: auto;
    }

    .friend-avatar {
        width: 40px;
        height: 40px;
    }

    .invite-action {
        padding: 0.4rem 0.8rem;
        font-size: 0.9rem;
    }
}
</style>
